using MediatR;
using S.O.Api.Write.Application.Command.Medical;
using S.O.Domain.Medical;
using S.O.ErrorCode;
using S.O.Interstructrue;
using S.O.Interstructrue.Base;

namespace S.O.Api.Write.Application.Handler.Medical
{
    /// <summary>
    /// 更新挂号记录处理器
    /// 支持患者修改挂号信息，如更换医生、调整就诊时间等
    /// </summary>
    public class UpdateRegistrationHandler : IRequestHandler<UpdateRegistrationCommand, APIResult<bool>>
    {
        /// <summary>
        /// 数据库上下文
        /// </summary>
        private readonly RBACDbContext _context;
        
        /// <summary>
        /// 挂号记录仓储
        /// </summary>
        private readonly IBaseRepository<RegistrationModel> _registrationRepository;

        /// <summary>
        /// 构造函数，通过依赖注入初始化所需服务
        /// </summary>
        /// <param name="context">数据库上下文</param>
        /// <param name="registrationRepository">挂号记录仓储</param>
        public UpdateRegistrationHandler(
            RBACDbContext context,
            IBaseRepository<RegistrationModel> registrationRepository)
        {
            _context = context;
            _registrationRepository = registrationRepository;
        }

        /// <summary>
        /// 处理更新挂号记录命令
        /// </summary>
        /// <param name="request">更新挂号记录命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>更新结果</returns>
        public async Task<APIResult<bool>> Handle(UpdateRegistrationCommand request, CancellationToken cancellationToken)
        {
            try
            {
                // 查找挂号记录
                var registration = _registrationRepository.GetModel(request.Id);
                if (registration == null || !registration.IsEnable)
                {
                    return new APIResult<bool> { Code = APIEnums.Error, Msg = "挂号记录不存在" };
                }
                
                // 检查挂号状态，已完成或已取消的挂号不能修改
                if (registration.Status == "已完成" || registration.Status == "已取消")
                {
                    return new APIResult<bool> { Code = APIEnums.Error, Msg = "该挂号记录已完成或已取消，无法修改" };
                }
                
                // 如果修改就诊日期，验证不能是过去的日期
                if (request.VisitDate.HasValue && request.VisitDate.Value.Date < DateTime.Now.Date)
                {
                    return new APIResult<bool> { Code = APIEnums.Error, Msg = "就诊日期不能早于当前日期" };
                }
                
                // 更新字段
                if (!string.IsNullOrEmpty(request.RegistrationType))
                    registration.RegistrationType = request.RegistrationType;
                    
                if (request.RegistrationFee.HasValue)
                    registration.RegistrationFee = request.RegistrationFee.Value;
                    
                if (request.OtherFee.HasValue)
                    registration.OtherFee = request.OtherFee.Value;
                    
                if (!string.IsNullOrEmpty(request.Department))
                    registration.Department = request.Department;
                    
                if (!string.IsNullOrEmpty(request.Doctor))
                    registration.Doctor = request.Doctor;
                    
                if (request.VisitDate.HasValue)
                    registration.VisitDate = request.VisitDate.Value;
                    
                if (!string.IsNullOrEmpty(request.Status))
                    registration.Status = request.Status;
                
                // 更新时间处理（如果需要可以添加UpdateTime字段到BaseEntity）
                
                // 保存更改
                _registrationRepository.Update(registration);
                _context.SaveChanges();
                
                return new APIResult<bool> { Code = APIEnums.Success, Data = true, Msg = "挂号信息更新成功" };
            }
            catch (Exception ex)
            {
                return new APIResult<bool> { Code = APIEnums.Error, Msg = $"更新挂号信息失败：{ex.Message}" };
            }
        }
    }
}